﻿using InterLock.Common;
using System.Collections.Generic;

namespace InterLock.Algorithm
{
    public class SearchAlgorithm
    {
        Queue<EquipmentNode> queueEquipmentNotBeSersearched = new Queue<EquipmentNode>();  //储存进路上未被搜索的节点
        EquipmentNode treeHead = new EquipmentNode();       //储存二叉树结构的进路

        #region 执行搜索
        /// <summary>
        /// 执行搜索
        /// </summary>
        /// <param name="beginE"></param>
        /// <param name="endE"></param>
        public EquipmentNode GetPath(Equipment beginE, Equipment endE)
        {
            treeHead = new EquipmentNode()
            {
                Data = beginE,
                Parent = null
            };
            EquipmentNode result;
            queueEquipmentNotBeSersearched.Clear();                    //将存储的节点清空

            if (beginE.X1 < endE.X1)           //判断搜索进路的方向
            {
                result = RSearch(beginE, endE, treeHead);
            }
            else
            {
                result = LSearch(beginE, endE, treeHead);
            }


            return result;
        }
        #endregion



        #region 往左搜索
        /// <summary>
        /// 往左搜索
        /// </summary>
        /// <param name="beginE"></param>
        /// <param name="endE"></param>
        /// <param name="parent"></param>
        /// <returns></returns>
        private EquipmentNode LSearch(Equipment beginE, Equipment endE, EquipmentNode parent)
        {
            TxtHelper.WriteTxt("Start Search");
            EquipmentNode tp = parent;
            Equipment p = beginE;
            while (p != null)
            {
                if (p == endE)
                {
                    queueEquipmentNotBeSersearched.Clear();                    //将存储的节点清空
                    TxtHelper.WriteTxt("End Search" + "\r\n");
                    return tp;
                }
                if (p.L != null)
                {
                    if (p.W != null && p.W.X1 < p.X1)
                    {
                        EquipmentNode lChild = new EquipmentNode();
                        lChild.Data = p.W;
                        lChild.Parent = tp;
                        queueEquipmentNotBeSersearched.Enqueue(lChild);
                    }

                    p = p.L;
                    EquipmentNode rChild = new EquipmentNode()
                    {
                        Data = p,
                        Parent = tp
                    };
                    tp = rChild;

                }
                else if (p.W != null)
                {

                    if (p.W.X1 > p.X1)                 //判断有岔进路方向是否正确
                    {
                        p = p.L;
                        EquipmentNode rChild = new EquipmentNode()
                        {
                            Data = p,
                            Parent = tp
                        };
                        tp = rChild;
                    }
                    else
                    {
                        p = p.W;
                        EquipmentNode lChild = new EquipmentNode()
                        {
                            Data = p,
                            Parent = tp
                        };
                        tp = lChild;
                    }
                }
                else if (queueEquipmentNotBeSersearched.Count != 0)
                {
                    EquipmentNode t = queueEquipmentNotBeSersearched.Dequeue();
                    p = t.Data;
                    tp = t;
                }
                else
                {
                    return null;
                }
                TxtHelper.WriteTxt(p.Name);
            }
            TxtHelper.WriteTxt("End Search" + "\r\n");
            return null;
        }
        #endregion

        #region 往右搜索
        /// <summary>
        /// 往右搜索
        /// </summary>
        /// <param name="endE"></param>
        /// <param name="parent"></param>
        /// <returns></returns>
        private EquipmentNode RSearch(Equipment beginE, Equipment endE, EquipmentNode parent)
        {
            TxtHelper.WriteTxt("Start Search");
            EquipmentNode tp = parent;
            Equipment p = beginE;
            while (p != null)
            {
                if (p.N == endE.N)
                {
                    queueEquipmentNotBeSersearched.Clear();                    //将存储的节点清空
                    TxtHelper.WriteTxt("End Search" + "\r\n");
                    return tp;
                }
                if (p.R != null)
                {
                    if (p.W != null && p.W.X1 > p.X1)
                    {
                        EquipmentNode lChild = new EquipmentNode();
                        lChild.Data = p.W;
                        lChild.Parent = tp;
                        queueEquipmentNotBeSersearched.Enqueue(lChild);
                    }

                    p = p.R;
                    EquipmentNode rChild = new EquipmentNode()
                    {
                        Data = p,
                        Parent = tp
                    };
                    tp = rChild;
                }
                else if (p.W != null)
                {
                    if (p.W.X1 < p.X1)                 //判断有岔进路方向是否正确
                    {
                        p = p.R;
                        EquipmentNode rChild = new EquipmentNode()
                        {
                            Data = p,
                            Parent = tp
                        };
                        tp = rChild;
                    }
                    else
                    {
                        p = p.W;
                        EquipmentNode lChild = new EquipmentNode()
                        {
                            Data = p,
                            Parent = tp
                        };
                        tp = lChild;
                    }
                }
                else if (queueEquipmentNotBeSersearched.Count != 0)
                {
                    EquipmentNode t = queueEquipmentNotBeSersearched.Dequeue();
                    p = t.Data;
                    tp = t;
                }
                else
                {
                    return null;
                }
                TxtHelper.WriteTxt(p.Name);
            }
            TxtHelper.WriteTxt("End Search" + "\r\n");
            return null;
        }
        #endregion
    }
}
